package com.example.everying.framework.ai.deepseek.service;


import com.example.everying.framework.ai.deepseek.DeepSeekException;
import com.example.everying.framework.ai.deepseek.domain.DeepSeekRequest;
import com.example.everying.framework.ai.deepseek.domain.DeepSeekRequestDto;
import com.example.everying.framework.ai.deepseek.domain.DeepSeekResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatusCode;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import java.util.List;

@Slf4j
@Service
@RequiredArgsConstructor // Lombok 自动生成构造函数
public class DeepSeekService {

    private final WebClient deepSeekWebClient; // 注入配置好的WebClient

    public Mono<String> callDeepSeek(DeepSeekRequestDto requestDto) {
        log.info("DeepSeek  请求参数：{}", requestDto);

        return deepSeekWebClient.post()
                .uri("/v1/chat/completions")
                .bodyValue(buildRequest(requestDto))
                .retrieve()
                .onStatus(HttpStatusCode::is4xxClientError, response ->
                        response.bodyToMono(String.class)
                                .flatMap(body -> {
                                    log.error(" 客户端错误响应: {}", body);
                                    return Mono.error(new DeepSeekException(
                                            response.statusCode(),
                                            "Client error: " + body
                                    ));
                                })
                )
                .onStatus(HttpStatusCode::is5xxServerError, response ->
                        response.bodyToMono(String.class)
                                .flatMap(body -> {
                                    log.error(" 服务端错误响应: {}", body);
                                    return Mono.error(new DeepSeekException(
                                            response.statusCode(),
                                            "Server error: " + body
                                    ));
                                })
                )
                .bodyToMono(DeepSeekResponse.class)
                .doOnNext(response -> {
                    String aiResponse = response.getChoices().get(0).getMessage().getContent();
                    log.info("AI 返回内容: {}", aiResponse);
                })
                .map(response -> response.getChoices().get(0).getMessage().getContent())
                .onErrorResume(DeepSeekException.class, e -> {
                    log.error("DeepSeek  API调用失败: {}", e.getMessage());
                    return Mono.just("Error  occurred: " + e.getMessage());
                })
                .doOnSubscribe(sub -> log.debug(" 开始DeepSeek API调用"))
                .doOnSuccess(res -> log.debug("DeepSeek  API调用成功"))
                .doOnError(e -> log.error("DeepSeek  API调用异常", e));
    }

    private DeepSeekRequest buildRequest(DeepSeekRequestDto dto) {
        String userMessage = String.format(
                "为以下文本生成一个20字以内的标题，要求简短有力，必须包含关键信息（如时间、地点、事件等），仅输出标题内容：%s",
                dto.getContent()
        );
        // 构建请求体
        DeepSeekRequest request = new DeepSeekRequest();
        request.setModel("deepseek-chat");
        request.setMessages(List.of(new DeepSeekRequest.Message("user", userMessage)));
        // 加速响应参数
        request.setMaxTokens(100);       // 限制响应长度（避免长文本延迟）
        request.setTemperature(0.3);     // 降低随机性（值越低响应越确定）
        request.setStream(false);        // 关闭流式传输（非流式通常更快）
        request.setTopP(0.9);            // 限制采样范围（加速生成）
        return request;
    }

    private ExchangeFilterFunction logRequest() {
        return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            System.out.println("Request:  " + clientRequest.method() + " " + clientRequest.url());
            return Mono.just(clientRequest);
        });
    }
}
